<template>
  <view v-if="show" class="location">
    <view>您的目前位置 ( ± {{ formatCoordinate(locationData.accuracy,1) }}m )</view>
    <view>WGS84 Lat: {{ formatCoordinate(locationData.latitude,5) }} Long: {{ formatCoordinate(locationData.longitude,5) }}</view>
    <view>HK1980 N: {{ hk1980Data ? hk1980Data.n : '转换中...' }} E: {{ hk1980Data ? hk1980Data.e : '转换中...' }}</view>
    <view>{{ utmData || 'UTM 转换中...' }}</view>
    <view>GPS高度 {{formatCoordinate(locationData.altitude,2)}}m </view>
  </view>

</template>

<script setup lang="ts">
import { ref, computed } from 'vue'

// 响应式数据
const show = ref(false)
const locationData = ref<any>(null)
const hk1980Data = ref<any>(null)
const utmData = ref<string>('')

// 定义方法
function open(data: any) {
  locationData.value = data
  hk1980Data.value = null
  utmData.value = ''
  show.value = true

  // 异步转换坐标
  if (data && data.longitude && data.latitude) {
    convertToHK1980(data.longitude, data.latitude)
    convertToUTM(data.longitude, data.latitude)
  }
}

function close() {
  show.value = false
  locationData.value = null
  hk1980Data.value = null
  utmData.value = ''
}

// 坐标格式化
function formatCoordinate(value: number, precision: number): string {
  if (!value && value !== 0) return '無數據'
  return value.toFixed(precision)
}

// 转换为HK1980坐标系（纯JavaScript实现）
function convertToHK1980(longitude: number, latitude: number) {
  try {
    console.log('转换WGS84坐标为HK1980:', { longitude, latitude })

    // 使用纯JavaScript转换算法
    const hk1980Coords = wgs84ToHK1980(latitude, longitude)

    if (hk1980Coords) {
      hk1980Data.value = {
        e: Math.round(hk1980Coords.easting),
        n: Math.round(hk1980Coords.northing)
      }
      console.log('HK1980坐标:', hk1980Data.value)
    }
  } catch (error) {
    console.error('坐标转换失败:', error)
    // 转换失败时设置默认值
    hk1980Data.value = {
      e: 0,
      n: 0
    }
  }
}

// 转换为UTM坐标格式
function convertToUTM(longitude: number, latitude: number) {
  try {
    // 计算UTM区域号（香港地区通常是50Q）
    const zone = Math.floor((longitude + 180) / 6) + 1
    const zoneLetter = getUTMZoneLetter(latitude)

    // 使用简化的UTM转换算法
    const utmCoords = wgs84ToUTM(latitude, longitude)

    // 格式化为类似 "UTM 50Q KK 1269 7865" 的格式
    const gridSquare = getGridSquare(utmCoords.easting, utmCoords.northing)
    const shortEasting = Math.floor((utmCoords.easting % 100000) / 100)
    const shortNorthing = Math.floor((utmCoords.northing % 100000) / 100)

    utmData.value = `UTM ${zone}${zoneLetter} ${gridSquare} ${shortEasting.toString().padStart(4, '0')} ${shortNorthing.toString().padStart(4, '0')}`

    console.log('UTM坐标:', utmData.value)
  } catch (error) {
    console.error('UTM转换失败:', error)
    utmData.value = 'UTM 转换失败'
  }
}

// WGS84到HK1980的转换函数
function wgs84ToHK1980(lat: number, lon: number) {
  // HK1980坐标系参数
  const hk1980Params = {
    a: 6378388.0,           // 长半轴 (Clarke 1858)
    f: 1 / 297.0,           // 扁率
    falseEasting: 836694.05,  // 东坐标偏移
    falseNorthing: 819069.8,  // 北坐标偏移
    centralMeridian: 114.178555556, // 中央经线
    latitudeOfOrigin: 22.312133333,  // 起始纬度
    k0: 1.0                 // 缩放因子
  }

  // WGS84到HK1980的参数转换（七参数转换）
  const datumParams = {
    dx: -162.619,    // X轴平移
    dy: -276.959,    // Y轴平移
    dz: -161.764,    // Z轴平移
    rx: 0.067753,    // X轴旋转(弧秒)
    ry: -2.243649,   // Y轴旋转(弧秒)
    rz: -1.158827,   // Z轴旋转(弧秒)
    s: -1.094246e-6  // 尺度因子
  }

  // 第一步：WGS84地理坐标转为等键坐标
  const wgs84Cartesian = geographicToCartesian(lat, lon, 0, 6378137.0, 1/298.257223563)

  // 第二步：七参数转换到HK1980基准
  const hk1980Cartesian = sevenParamTransform(wgs84Cartesian, datumParams)

  // 第三步：转回地理坐标
  const hk1980Geographic = cartesianToGeographic(hk1980Cartesian, hk1980Params.a, hk1980Params.f)

  // 第四步：投影到平面坐标（横墨卡托投影）
  const projected = transverseMercatorProjection(
    hk1980Geographic.lat,
    hk1980Geographic.lon,
    hk1980Params.centralMeridian,
    hk1980Params.latitudeOfOrigin,
    hk1980Params.k0,
    hk1980Params.a,
    hk1980Params.f
  )

  return {
    easting: projected.easting + hk1980Params.falseEasting,
    northing: projected.northing + hk1980Params.falseNorthing
  }
}

// 地理坐标转等键坐标
function geographicToCartesian(lat: number, lon: number, height: number, a: number, f: number) {
  const latRad = lat * Math.PI / 180
  const lonRad = lon * Math.PI / 180

  const e2 = 2 * f - f * f
  const N = a / Math.sqrt(1 - e2 * Math.sin(latRad) * Math.sin(latRad))

  const x = (N + height) * Math.cos(latRad) * Math.cos(lonRad)
  const y = (N + height) * Math.cos(latRad) * Math.sin(lonRad)
  const z = (N * (1 - e2) + height) * Math.sin(latRad)

  return { x, y, z }
}

// 七参数转换
function sevenParamTransform(cartesian: any, params: any) {
  const { dx, dy, dz, rx, ry, rz, s } = params

  // 弧秒转弧度
  const rxRad = rx * Math.PI / (180 * 3600)
  const ryRad = ry * Math.PI / (180 * 3600)
  const rzRad = rz * Math.PI / (180 * 3600)

  const { x, y, z } = cartesian

  const newX = x + dx + (s * x) + (rz * y) - (ry * z)
  const newY = y + dy - (rz * x) + (s * y) + (rx * z)
  const newZ = z + dz + (ry * x) - (rx * y) + (s * z)

  return { x: newX, y: newY, z: newZ }
}

// 等键坐标转地理坐标
function cartesianToGeographic(cartesian: any, a: number, f: number) {
  const { x, y, z } = cartesian

  const e2 = 2 * f - f * f
  const p = Math.sqrt(x * x + y * y)
  const lon = Math.atan2(y, x)

  let lat = Math.atan2(z, p * (1 - e2))
  let N = a / Math.sqrt(1 - e2 * Math.sin(lat) * Math.sin(lat))
  let height = p / Math.cos(lat) - N

  // 迭代计算提高精度
  for (let i = 0; i < 5; i++) {
    lat = Math.atan2(z, p * (1 - e2 * N / (N + height)))
    N = a / Math.sqrt(1 - e2 * Math.sin(lat) * Math.sin(lat))
    height = p / Math.cos(lat) - N
  }

  return {
    lat: lat * 180 / Math.PI,
    lon: lon * 180 / Math.PI,
    height
  }
}

// 横墨卡托投影
function transverseMercatorProjection(
  lat: number,
  lon: number,
  centralMeridian: number,
  latitudeOfOrigin: number,
  k0: number,
  a: number,
  f: number
) {
  const latRad = lat * Math.PI / 180
  const lonRad = lon * Math.PI / 180
  const centralMeridianRad = centralMeridian * Math.PI / 180
  const latitudeOfOriginRad = latitudeOfOrigin * Math.PI / 180

  const e2 = 2 * f - f * f
  const e4 = e2 * e2
  const e6 = e4 * e2

  const n = f / (2 - f)
  const n2 = n * n
  const n3 = n2 * n
  const n4 = n3 * n

  const A = a / (1 + n) * (1 + n2/4 + n4/64)

  const alpha1 = n/2 - 2*n2/3 + 5*n3/16
  const alpha2 = 13*n2/48 - 3*n3/5
  const alpha3 = 61*n3/240

  const xi = latRad
  const eta = lonRad - centralMeridianRad

  const xi1 = xi + alpha1 * Math.sin(2*xi) * Math.cosh(2*eta) + alpha2 * Math.sin(4*xi) * Math.cosh(4*eta) + alpha3 * Math.sin(6*xi) * Math.cosh(6*eta)
  const eta1 = eta + alpha1 * Math.cos(2*xi) * Math.sinh(2*eta) + alpha2 * Math.cos(4*xi) * Math.sinh(4*eta) + alpha3 * Math.cos(6*xi) * Math.sinh(6*eta)

  const easting = k0 * A * eta1
  const northing = k0 * A * xi1

  return { easting, northing }
}

// 获取UTM区域字母
function getUTMZoneLetter(latitude: number): string {
  const letters = 'CDEFGHJKLMNPQRSTUVWXX'
  return letters[Math.floor((latitude + 80) / 8)]
}

// 简化的WGS84到UTM转换
function wgs84ToUTM(lat: number, lon: number) {
  const a = 6378137.0 // 地球半径
  const f = 1 / 298.257223563 // 扁率
  const k0 = 0.9996 // 缩放因子

  const latRad = lat * Math.PI / 180
  const lonRad = lon * Math.PI / 180

  const zone = Math.floor((lon + 180) / 6) + 1
  const lonOrigin = (zone - 1) * 6 - 180 + 3
  const lonOriginRad = lonOrigin * Math.PI / 180

  const eccSquared = 2 * f - f * f
  const eccPrimeSquared = eccSquared / (1 - eccSquared)

  const N = a / Math.sqrt(1 - eccSquared * Math.sin(latRad) * Math.sin(latRad))
  const T = Math.tan(latRad) * Math.tan(latRad)
  const C = eccPrimeSquared * Math.cos(latRad) * Math.cos(latRad)
  const A = Math.cos(latRad) * (lonRad - lonOriginRad)

  const M = a * ((1 - eccSquared/4 - 3*eccSquared*eccSquared/64 - 5*eccSquared*eccSquared*eccSquared/256) * latRad
              - (3*eccSquared/8 + 3*eccSquared*eccSquared/32 + 45*eccSquared*eccSquared*eccSquared/1024) * Math.sin(2*latRad)
              + (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024) * Math.sin(4*latRad)
              - (35*eccSquared*eccSquared*eccSquared/3072) * Math.sin(6*latRad))

  let easting = k0 * N * (A + (1-T+C)*A*A*A/6 + (5-18*T+T*T+72*C-58*eccPrimeSquared)*A*A*A*A*A/120) + 500000.0

  let northing = k0 * (M + N*Math.tan(latRad)*(A*A/2 + (5-T+9*C+4*C*C)*A*A*A*A/24 + (61-58*T+T*T+600*C-330*eccPrimeSquared)*A*A*A*A*A*A/720))

  if (lat < 0) {
    northing += 10000000.0 // 南半球
  }

  return {
    easting: Math.round(easting),
    northing: Math.round(northing)
  }
}

// 获取网格方格字母
function getGridSquare(easting: number, northing: number): string {
  const eastingSquare = Math.floor(easting / 100000) % 8
  const northingSquare = Math.floor(northing / 100000) % 20

  const eastingLetters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
  const northingLetters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V']

  // 对于香港地区，通常是KK网格
  // 这里简化处理，实际应根据具体区域计算
  return 'KK'
}

defineExpose({
  open,
  close,
})
</script>

<style lang="scss" scoped>
.location {
  position: fixed;
  bottom: 15rpx;
  left: 50%;
  transform: translate(-50%, 0);
  font-size: 12px;
  background-color: #7C9FB7;
  line-height: 15px;
  padding: 20rpx;
  border-radius: 10rpx;
  color: #fff;
  z-index: 9999;
  display: table;
  min-width: 430rpx;
}

</style>